// function dynamicAdd() {
//     return [...arguments].reduce((pre, cur) => {
//         return pre + cur
//     }, 0)
// }

// function curry(fn, firstArg) {
//     return function() {
//         const restArgs = [...arguments]
//         return fn.apply(this, [firstArg, ...restArgs])
//     }
// }

// const add10 = curry(dynamicAdd, 10)
// const add20 = curry(dynamicAdd, 20)
// const anotherAdd20 = curry(add10, 10)
// console.log(anotherAdd20(5))

//参数定长
function fn(a, b, c) {
    return a + b + c
}

// function curry(fn) {
//     const argLen = fn.length
//     const presetArgs = [...arguments].slice(1)
//     return function() {
//         const restArgs = [...arguments]
//         const allArgs = [...presetArgs, ...restArgs]
//         if(allArgs.length >= argLen) {
//             return fn.apply(this, allArgs)
//         } else {
//             return curry.call(null, fn, ...allArgs)
//         }
//     }
// }

// const curried = curry(fn)
// console.log(curried(1)(2)(3))


//参数不定长
function curry(fn) {
    const presetArgs = [...arguments].slice(1)

    function curried() {
        const restArgs = [...arguments]
        const allArgs = [...presetArgs, ...restArgs]
        return curry.call(null, fn, ...allArgs)
    }

    curried.toString = function() {
        return fn.apply(this, presetArgs)
    }

    return curried
}

function dynamicAdd() {
    return [...arguments].reduce((prev, curr) => {
        return prev + curr
    }, 0)
}
var add = curry(dynamicAdd);
let res = add(1)(2)(3)(4) // 10
let res2 = add(1, 2)(3, 4)(5, 6) // 21
//用变量接受来触发函数的隐式转换, nodeJS环境运行会失效, 最好在浏览器调试
console.log(res)

